package com.halfsword.creativecraft.datagen;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.halfsword.creativecraft.CreativeCraft;
import com.halfsword.creativecraft.block.BlockLoader;
import com.halfsword.creativecraft.item.ItemLoader;
import com.halfsword.creativecraft.recipe.SpaceCollectorRecipe;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.data.PackOutput;
import net.minecraft.data.recipes.*;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.crafting.AbstractCookingRecipe;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeSerializer;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.Blocks;
import net.minecraftforge.common.crafting.conditions.IConditionBuilder;

import javax.annotation.Nullable;
import java.util.List;
import java.util.function.Consumer;

public class SpaceRecipeProvider extends RecipeProvider implements IConditionBuilder {
    private static final List<ItemLike> SPACE_SMELTABLES = List.of(
            ItemLoader.RAWSPACE.get(),
            BlockLoader.ORE_SPACE.get(),
            BlockLoader.DEEPSLATE_ORE_SPACE.get(),
            BlockLoader.END_ORE_SPACE.get(),
            BlockLoader.NETHER_ORE_SPACE.get()
    );

    public SpaceRecipeProvider(PackOutput output) {
        super(output);
    }

    @Override
    protected void buildRecipes(Consumer<FinishedRecipe> consumer) {
        // 空间碎片方块合成配方
        ShapedRecipeBuilder.shaped(RecipeCategory.MISC, BlockLoader.BLOCK_SPACE.get())
                .pattern("###")
                .pattern("###")
                .pattern("###")
                .define('#', ItemLoader.GEMSPACE.get())
                .unlockedBy("has_gemspace", has(ItemLoader.GEMSPACE.get()))
                .save(consumer, ResourceLocation.fromNamespaceAndPath(CreativeCraft.MOD_ID, "block_space_from_gemspace"));

        // 钛块合成配方
        ShapedRecipeBuilder.shaped(RecipeCategory.MISC, BlockLoader.BLOCK_TITANIUM.get())
                .pattern("###")
                .pattern("###")
                .pattern("###")
                .define('#', ItemLoader.INGOT_TITANIUM.get())
                .unlockedBy("has_titanium_ingot", has(ItemLoader.INGOT_TITANIUM.get()))
                .save(consumer, ResourceLocation.fromNamespaceAndPath(CreativeCraft.MOD_ID, "block_titanium_from_ingot"));

        // 空间碎片解压缩配方
        ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, ItemLoader.GEMSPACE.get(), 9)
                .requires(BlockLoader.BLOCK_SPACE.get())
                .unlockedBy("has_block_space", has(BlockLoader.BLOCK_SPACE.get()))
                .save(consumer, ResourceLocation.fromNamespaceAndPath(CreativeCraft.MOD_ID, "gemspace_from_block_space"));

        // 钛锭解压缩配方
        ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, ItemLoader.INGOT_TITANIUM.get(), 9)
                .requires(BlockLoader.BLOCK_TITANIUM.get())
                .unlockedBy("has_block_titanium", has(BlockLoader.BLOCK_TITANIUM.get()))
                .save(consumer, ResourceLocation.fromNamespaceAndPath(CreativeCraft.MOD_ID, "titanium_ingot_from_block"));

        // 熔炼配方
        oreSmelting(consumer, SPACE_SMELTABLES, RecipeCategory.MISC, ItemLoader.GEMSPACE.get(), 10f, 1200, "gemspace");
        oreBlasting(consumer, SPACE_SMELTABLES, RecipeCategory.MISC, ItemLoader.GEMSPACE.get(), 10f, 1000, "gemspace");

        // 空间碎片收集器配方
        addCollectorRecipes(consumer);

        // 蒸汽破碎机配方
        addSteamCrusherRecipes(consumer);
    }

    // ================= 蒸汽破碎机配方 =================
    private void addSteamCrusherRecipes(Consumer<FinishedRecipe> consumer) {
        // 圆石 -> 沙子
        steamCrusherRecipe(consumer, "cobblestone_to_sand",
                List.of(Ingredient.of(Items.COBBLESTONE)),
                new ItemStack(Items.SAND, 1),
                new ItemStack(Items.FLINT, 1),  // 副产品：燧石
                200
        );

        // 石头 -> 沙砾
        steamCrusherRecipe(consumer, "stone_to_gravel",
                List.of(Ingredient.of(Items.STONE)),
                new ItemStack(Items.GRAVEL, 1),
                new ItemStack(Items.FLINT, 1),  // 副产品：燧石
                200
        );

        // 沙砾 -> 沙子
        steamCrusherRecipe(consumer, "gravel_to_sand",
                List.of(Ingredient.of(Items.GRAVEL)),
                new ItemStack(Items.SAND, 1),
                new ItemStack(Items.FLINT, 1),  // 副产品：燧石
                150
        );







        // 下界石英矿石 -> 石英
        steamCrusherRecipe(consumer, "nether_quartz_ore_to_quartz",
                List.of(Ingredient.of(Items.NETHER_QUARTZ_ORE)),
                new ItemStack(Items.QUARTZ, 4),
                new ItemStack(Items.GOLD_NUGGET, 1),  // 副产品：金粒
                350
        );


    }

    /**
     * 添加蒸汽破碎机配方
     *
     * @param consumer 配方消费者
     * @param name 配方名称（唯一标识）
     * @param ingredients 原料列表
     * @param result 主输出物品
     * @param byproduct 副产品（可选）
     * @param processingTime 处理时间（ticks）
     */
    private void steamCrusherRecipe(Consumer<FinishedRecipe> consumer, String name,
                                    List<Ingredient> ingredients,
                                    ItemStack result,
                                    @Nullable ItemStack byproduct,
                                    int processingTime) {
        ResourceLocation id = ResourceLocation.fromNamespaceAndPath(CreativeCraft.MOD_ID, "steam_crushing/" + name);

        consumer.accept(new FinishedRecipe() {
            @Override
            public void serializeRecipeData(JsonObject json) {
                // 配方类型标识
                json.addProperty("type", CreativeCraft.MOD_ID + ":unfried_steam_crushing");

                // 分组（可选）
                json.addProperty("group", "steam_crusher");

                // 原料列表
                JsonArray ingredientsArray = new JsonArray();
                for (Ingredient ingredient : ingredients) {
                    ingredientsArray.add(ingredient.toJson());
                }
                json.add("ingredients", ingredientsArray);

                // 主输出物品
                JsonObject resultObj = new JsonObject();
                ResourceLocation resultId = BuiltInRegistries.ITEM.getKey(result.getItem());
                resultObj.addProperty("item", resultId.toString());
                if (result.getCount() > 1) {
                    resultObj.addProperty("count", result.getCount());
                }
                json.add("result", resultObj);

                // 副产品（可选）
                if (byproduct != null && !byproduct.isEmpty()) {
                    JsonObject byproductObj = new JsonObject();
                    ResourceLocation byproductId = BuiltInRegistries.ITEM.getKey(byproduct.getItem());
                    byproductObj.addProperty("item", byproductId.toString());
                    if (byproduct.getCount() > 1) {
                        byproductObj.addProperty("count", byproduct.getCount());
                    }
                    json.add("byproduct", byproductObj);
                }

                // 处理时间
                json.addProperty("processing_time", processingTime);
            }

            @Override
            public ResourceLocation getId() {
                return id;
            }

            @Override
            public RecipeSerializer<?> getType() {
                return RecipeSerializer.SMELTING_RECIPE; // 使用默认序列化器，实际由MOD处理
            }

            @Override
            public JsonObject serializeAdvancement() {
                return null;
            }

            @Override
            public ResourceLocation getAdvancementId() {
                return null;
            }
        });
    }

    // ================= 收集器配方 =================
    private void addCollectorRecipes(Consumer<FinishedRecipe> consumer) {
        collectorRecipe(consumer, "ore_space", true,
                List.of(
                        Ingredient.of(Blocks.STONE),
                        Ingredient.of(Blocks.STONE),
                        Ingredient.of(Blocks.STONE),
                        Ingredient.of(Blocks.STONE)
                ),
                new ItemStack(BlockLoader.ORE_SPACE.get(), 1),
                2000,
                ResourceLocation.fromNamespaceAndPath("minecraft", "overworld"),
                40,
                256
        );

        collectorRecipe(consumer, "deepslate_ore_space", true,
                List.of(
                        Ingredient.of(Blocks.DEEPSLATE),
                        Ingredient.of(Blocks.DEEPSLATE),
                        Ingredient.of(Blocks.DEEPSLATE),
                        Ingredient.of(Blocks.DEEPSLATE)
                ),
                new ItemStack(BlockLoader.DEEPSLATE_ORE_SPACE.get(), 1),
                2000,
                ResourceLocation.fromNamespaceAndPath("minecraft", "overworld"),
                -64,
                40
        );

        collectorRecipe(consumer, "nether_ore_space", true,
                List.of(
                        Ingredient.of(Blocks.NETHERRACK),
                        Ingredient.of(Blocks.BLACKSTONE),
                        Ingredient.of(Blocks.NETHERRACK),
                        Ingredient.of(Blocks.BLACKSTONE)
                ),
                new ItemStack(BlockLoader.NETHER_ORE_SPACE.get(), 1),
                2000,
                ResourceLocation.fromNamespaceAndPath("minecraft", "the_nether"),
                -64,
                256
        );

        collectorRecipe(consumer, "end_ore_space", true,
                List.of(
                        Ingredient.of(Blocks.OBSIDIAN),
                        Ingredient.of(Blocks.END_STONE),
                        Ingredient.of(Blocks.OBSIDIAN),
                        Ingredient.of(Blocks.END_STONE)
                ),
                new ItemStack(BlockLoader.END_ORE_SPACE.get(), 1),
                2000,
                ResourceLocation.fromNamespaceAndPath("minecraft", "the_end"),
                -64,
                256
        );
    }

    /**
     * 添加空间收集器配方（支持新属性）
     */
    private void collectorRecipe(Consumer<FinishedRecipe> consumer, String name,
                                 boolean shapeless,
                                 List<Ingredient> ingredients,
                                 ItemStack output,
                                 int processingTime,
                                 ResourceLocation dimension,
                                 int minHeight,
                                 int maxHeight) {
        ResourceLocation id = ResourceLocation.fromNamespaceAndPath(CreativeCraft.MOD_ID, "collector/" + name);

        consumer.accept(new FinishedRecipe() {
            @Override
            public void serializeRecipeData(JsonObject json) {
                // 配方类型标识
                json.addProperty("type", SpaceCollectorRecipe.Serializer.ID.toString());

                // 配方模式（有序/无序）
                json.addProperty("shapeless", shapeless);

                // 处理时间
                json.addProperty("processing_time", processingTime);

                // 高度限制
                json.addProperty("min_height", minHeight);
                json.addProperty("max_height", maxHeight);

                // 维度限制（可选）
                if (dimension != null) {
                    json.addProperty("dimension", dimension.toString());
                }

                // 原料列表
                JsonArray ingredientsArray = new JsonArray();
                for (Ingredient ingredient : ingredients) {
                    ingredientsArray.add(ingredient.toJson());
                }
                json.add("ingredients", ingredientsArray);

                // 输出物品
                JsonObject outputObj = new JsonObject();
                ResourceLocation itemId = BuiltInRegistries.ITEM.getKey(output.getItem());
                outputObj.addProperty("item", itemId.toString());

                if (output.getCount() > 1) {
                    outputObj.addProperty("count", output.getCount());
                }
                json.add("output", outputObj);
            }

            @Override
            public ResourceLocation getId() {
                return id;
            }

            @Override
            public RecipeSerializer<?> getType() {
                return SpaceCollectorRecipe.Serializer.INSTANCE;
            }

            @Override
            public JsonObject serializeAdvancement() {
                return null;
            }

            @Override
            public ResourceLocation getAdvancementId() {
                return null;
            }
        });
    }

    // ================= 熔炼配方方法 =================
    protected static void oreSmelting(Consumer<FinishedRecipe> consumer, List<ItemLike> inputs,
                                      RecipeCategory category, ItemLike output,
                                      float experience, int cookingTime, String group) {
        oreCooking(consumer, RecipeSerializer.SMELTING_RECIPE, inputs, category,
                output, experience, cookingTime, group, "_from_smelting");
    }

    protected static void oreBlasting(Consumer<FinishedRecipe> consumer, List<ItemLike> inputs,
                                      RecipeCategory category, ItemLike output,
                                      float experience, int cookingTime, String group) {
        oreCooking(consumer, RecipeSerializer.BLASTING_RECIPE, inputs, category,
                output, experience, cookingTime, group, "_from_blasting");
    }

    protected static void oreCooking(Consumer<FinishedRecipe> consumer,
                                     RecipeSerializer<? extends AbstractCookingRecipe> serializer,
                                     List<ItemLike> inputs, RecipeCategory category,
                                     ItemLike output, float experience, int cookingTime,
                                     String group, String suffix) {
        for(ItemLike input : inputs) {
            String recipeName = getItemName(output) + suffix + "_" + getItemName(input);
            SimpleCookingRecipeBuilder.generic(Ingredient.of(input), category, output,
                            experience, cookingTime, serializer)
                    .group(group)
                    .unlockedBy(getHasName(input), has(input))
                    .save(consumer, ResourceLocation.fromNamespaceAndPath(CreativeCraft.MOD_ID, recipeName));
        }
    }

    // ================= 辅助方法 =================
    private static String getItemName(Item item) {
        return BuiltInRegistries.ITEM.getKey(item).getPath();
    }

    protected static String getHasName(ItemLike item) {
        return "has_" + getItemName(item.asItem());
    }
}